﻿using System;
using System.Linq;
using System.Collections.Generic;

namespace Boxi.Model
{
    public class MoveHistoryList
    {
        #region Indexer

        /// <summary>
        /// 
        /// </summary>
        public MoveHistoryModel this[Byte i]
        {
            get
            {
                if (i >= Length)
                    throw new Exception(String.Format("index {0} can not be called", i));

                return _moves[i];
            }
            set
            {
                if (i >= Length)
                    throw new Exception(String.Format("index {0} can not be set", i));

                _moves[i] = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public MoveHistoryModel this[Int32 i]
        {
            get
            {
                return this[Convert.ToByte(i)];
            }
            set {
                this[Convert.ToByte(i)] = value;
            }
        }
        private MoveHistoryModel[] _moves;
        #endregion
        #region Properties
        public Byte Length
        {
            get
            {
                return (Byte)_moves.Length;
            }
        }
        #endregion
        #region Constructors
        /// <summary>
        /// 
        /// </summary>
        /// <param name="length"></param>
        public MoveHistoryList(Byte length)
        {
            _moves = new MoveHistoryModel[length];
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="moves"></param>
        public MoveHistoryList(MoveHistoryModel[] moves)
        {
            _moves = moves;
        }
        #endregion
        #region Methods
        public MoveHistoryList Copy()
        {
            var result = new MoveHistoryModel[_moves.Length];
            for (Byte i = 0; i < _moves.Length; i++)
                result[i] = this[i];
            return new MoveHistoryList(result);
        }
        public MoveHistoryModel[] Where(Func<MoveHistoryModel, Boolean> search)
        {
            return _moves.Where(m => m.MoveID > 0).Where(search).ToArray();
        }
        public Boolean Contains(Byte moveID)
        {
            var result = false;
            for (Byte i = 0; i < _moves.Length; i++)
            {
                if (_moves[i].MoveID == 0 && moveID != 0)
                {
                    break;
                }
                else if (_moves[i].MoveID == moveID)
                {
                    result = true;
                    break;
                }
            }
            return result;
        }
        public Int32 GetOpenMoveCount()
        {
            Byte openMoves = 0;
            for (Byte i = 0; i < _moves.Length; i++)
                if (_moves[i].MoveID == 0)
                    openMoves += 1;

            return openMoves;
        }
        public MoveHistoryModel GetByID(Byte id)
        {
            for (Byte i = 0; i < _moves.Length; i++)
            {
                if (_moves[i].MoveID == id)
                    return _moves[i];
            }
            return default(MoveHistoryModel);
        }

        public Byte GetScore(SByte playerID)
        {
            Byte score = 0;
            var userMoves = _moves.Where(m => m.PlayerID == playerID).ToArray();
            for (Byte i = 0; i < userMoves.Length; i++)
                score += (Byte)userMoves[i].Points.Length;
            return score;
        }

        public Byte GetNextMoveNumber()
        {
            for (Byte i = 0; i < _moves.Length; i++)
                if (_moves[i].MoveID == 0)
                    return (Byte)(i + 1);

            return 0;
        }

        public Byte GetMoveOrder(Byte moveID)
        {
            for (Byte i = 0; i < _moves.Length; i++)
            {
                if (_moves[i].MoveID == moveID)
                    return i;
            }
            return 0;
        }
        public Int32 GetPlayerID(PointModel point)
        {
            Byte highest = 0;
            SByte playerID = 0;

            for (Byte i = 0; i < 4; i++)
            {
                Byte order = GetMoveOrder(point[i]);
                if (order == 0)
                    return 0;

                if (_moves[order].MoveMadeOrder > highest)
                {
                    highest = _moves[order].MoveMadeOrder;
                    playerID = _moves[order].PlayerID;
                }
            }
            return playerID;
        }

        public Byte[] GetOpenMoveIDs(PointModel point)
        {
            var mopenMoveIDs = new List<Byte>();
            for (Byte i = 0; i < 4; i++)
            {
                if (!Contains(point[i]))
                    mopenMoveIDs.Add(point[i]);
            }
            return mopenMoveIDs.ToArray();
        }
        public override string ToString()
        {
            var result = String.Empty;
            for (Byte i = 0; i < _moves.Length; i++)
                result += ((result == String.Empty) ? String.Empty : ",") + _moves[i].MoveID;

            return result;
        }
        #endregion
    }
}
